package com.ruoyi.utils.wx;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.utils.json.JsonUtils;
import com.ruoyi.wwxkf.vo.WwxSyncMsg;
import com.ruoyi.wxgzh.vo.ArticleContent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * 微信公众号的网络请求
 */
@Slf4j
public class WwNetWorkUtil {

    public static void main(String[] args) throws IOException {
//        String filePath = "C:\\Users\\Administrator\\Pictures\\1.jpg";
//        File file = new File(filePath);
//        FileInputStream input = new FileInputStream(file);
//        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "image/jpeg", input);
//        String s = addMaterial(tempToken, multipartFile,"image");
//        System.out.println(s);
        // 永久素材照片 : h2PpT3OXvnMCi-wlWFLayO-e0TJqdODQdyZLr63G3wCGjxtFVdqLOM9kScsNwRN0
        ArticleContent articleContent = new ArticleContent();
        articleContent.setTitle("测试一篇测试文稿");
        articleContent.setAuthor("派元官方");
        articleContent.setContent("测试u内容");
        articleContent.setThumb_media_id("h2PpT3OXvnMCi-wlWFLayO-e0TJqdODQdyZLr63G3wCGjxtFVdqLOM9kScsNwRN0");
        addDraftArticle(tempToken,articleContent);
    }

    /**
     * 微信客服接口请求网关
     */
    private static String baseUrl = "https://api.weixin.qq.com/cgi-bin";
    private static String corpid = "wxf25dba767ab10562";
    private static String corpsecret = "c6af9c87129710cf56e65cec76ca9894";
    private static String tempToken = "90_znRbR-yKehj_SyhV_ep7P1bM2CurgPK0npyflp8-jx96zN3G7kT71L3siO9EJBsnkJVyTJHJ6tyreQyEQTeoW2UVEd0zLdoL0Y4RhYxSV0UECCmrk15ZORGWYrcYZQcAEANOF";

    /**
     * 获取token
     *
     * @return
     */
    public static String getAccessToken() {
        // 动态获取当前方法名称
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        try {
            String resultStr = HttpUtil.get(baseUrl + "/token?grant_type=client_credential&appid=" + corpid + "&secret=" + corpsecret);
            String access_token = JsonUtils.parseMiddleData(resultStr, "access_token");
            if (StrUtil.isBlank(access_token)) {
                errorCatch(resultStr, methodName);
            }
            log.error("生成的access_token:{}", access_token);
            return access_token;
        } catch (Exception e) {
            log.error("微信公众号请求错误：【{}】", methodName);
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 新增永久素材
     * https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Adding_Permanent_Assets.html  参考文档
     *
     * @param token
     * @param multipartFile
     * @return mediaId
     */
    public static String addMaterial(String token, MultipartFile multipartFile,String type) {

        // 动态获取当前方法名称
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        try {
            if (Objects.isNull(multipartFile) || multipartFile.isEmpty()) {
                throw new RuntimeException("素材文件为空");
            }
            //链式构建请求
            String resultStr = HttpRequest.post(baseUrl + "/material/add_material?access_token=" + token+"&type="+type)
                    .form("media", getInputStream(multipartFile))
                    .timeout(3000)
                    .execute()
                    .body();

            String media_id = JsonUtils.parseMiddleData(resultStr, "media_id");
            if (StrUtil.isBlank(media_id)) {
                errorCatch(resultStr, methodName);
            }
            log.info("图片上传成功地址：【{}】", media_id);
            return media_id;
        } catch (Exception e) {
            log.error("微信公众号请求错误：【{}】", methodName);
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 新建草稿
     * https://developers.weixin.qq.com/doc/offiaccount/Draft_Box/Add_draft.html 参考文档
     * @param token
     * @param articleContent
     */
    public static void addDraftArticle(String token, ArticleContent articleContent) {

        // 动态获取当前方法名称
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        try {
            //消息体

            HashMap<Object, Object> bodyParam = new HashMap<>();
            List<ArticleContent> articleContents = new ArrayList<>();
            articleContents.add(articleContent);
            bodyParam.put("articles",articleContents);

            //使用hutool请求接口
            String bodyParamString = JSONObject.toJSONString(bodyParam);
            //链式构建请求
            String resultStr = HttpRequest.post(baseUrl + "/draft/add?access_token=" + token)
                    .header("Content-Type", "application/json")
                    .body(bodyParamString)//表单内容
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            //校验错误
            errorCatch(resultStr, methodName);
            String errmsg = JsonUtils.parseMiddleData(resultStr, "errmsg");
            log.info("用户【{}】,新建草稿成功：{}",1, errmsg);

        } catch (Exception e) {
            log.error("微信公众号网络请求方法【{}】请求错误", methodName);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 对消息体进行校验
     *
     * @param returnMsg    微信方法返回的信息
     * @param functionName 执行的方法名称
     */
    public static void errorCatch(String returnMsg, String functionName) {
        Map<String, String> errorMap = getErrorMap();
        String errcode = JsonUtils.parseMiddleData(returnMsg, "errcode");
        if (StrUtil.equals(errcode, "0")) {
            return;
        }
        String errorMessage = errorMap.get(errcode);
        if (errorMessage != null) {
            log.error("微信公众号网络请求方法【{}】请求错误, 错误原因：{}", functionName, errorMessage);
            throw new RuntimeException(errorMessage);
        }

        log.error("微信公众号网络请求方法【{}】请求错误, 报文全文：{}", functionName, returnMsg);
        throw new RuntimeException("微信请求解析错误");
    }


    public static WwxSyncMsg catchSyncMsgRsutl(long send_time, String openKfid, List<WwxSyncMsg> wwxSyncMsgs, Integer origin) {

        Optional<WwxSyncMsg> result = wwxSyncMsgs.stream()
                .filter(msg -> msg.getSend_time() == send_time && msg.getOpen_kfid().equals(openKfid) && msg.getOrigin() == origin) // 筛选条件
                .max(Comparator.comparingLong(WwxSyncMsg::getSend_time)); // 获取 send_time 最大的一条

        // 判断是否找到符合条件的记录
        if (result.isPresent()) {
            WwxSyncMsg targetMsg = result.get();
            log.info("方法【catchSyncMsgRsutl】找到符合条件的记录消息: " + targetMsg);
            return targetMsg;
        } else {
            return null;
        }
    }


    /**
     * 获取错误映射
     *
     * @return
     */
    public static Map<String, String> getErrorMap() {
        Map<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("-1", "系统繁忙，此时请开发者稍候再试");
        objectObjectHashMap.put("0", "请求成功");
        objectObjectHashMap.put("40001", "AppSecret错误或者AppSecret不属于这个公众号，请开发者确认AppSecret的正确性");
        objectObjectHashMap.put("40002", "请确保grant_type字段值为client_credential");
        objectObjectHashMap.put("40164", "调用接口的IP地址不在白名单中，请在接口IP白名单中进行设置。");
        objectObjectHashMap.put("40243", "AppSecret已被冻结，请登录MP解冻后再次调用。");
        objectObjectHashMap.put("89503", "此IP调用需要管理员确认,请联系管理员");
        objectObjectHashMap.put("89501", "此IP正在等待管理员确认,请联系管理员");
        objectObjectHashMap.put("89506", "24小时内该IP被管理员拒绝调用两次，24小时内不可再使用该IP调用");
        objectObjectHashMap.put("89507", "1小时内该IP被管理员拒绝调用一次，1小时内不可再使用该IP调用");
        return objectObjectHashMap;
    }

    /**
     * 获取上传文件的输入流
     *
     * @param file
     * @return
     */
    private static InputStreamResource getInputStream(MultipartFile file) {
        InputStreamResource isr = null;
        try {
            isr = new InputStreamResource(file.getInputStream(), file.getOriginalFilename());
        } catch (IOException e) {
            log.info("文件流转换异常:{}", e.getMessage());
        }
        return isr;
    }
}
